from django.db import models
import uuid
import re
from urllib.parse import urlparse
from django.core.exceptions import ValidationError
def check_url(url):
    """
    检查给定的字符串是否为正确的网络下载地址格式。
    参数:
    url (str): 需要检查的字符串，代表可能的网络下载地址。
    返回:
    bool: 如果是正确的网络下载地址格式返回True，否则返回False。
    """
    try:
        parsed_url = urlparse(url)
        if not (parsed_url.scheme and parsed_url.netloc):
            raise ValidationError('无效的URL格式，必须包含协议和网络位置部分')
        # 这里还可以添加更多复杂的验证逻辑，比如检查协议是否是常见的http、https等
        return True
    except ValueError as e:
        raise ValidationError(f'解析URL出现错误: {str(e)}')
"""
Django 数据库迁移命令: 
python manage.py makemigrations
python manage.py migrate
"""

class User(models.Model):
    """用户模型"""
    username = models.CharField(
        max_length=100, 
        unique=True, 
        verbose_name="用户名",
        error_messages={
            'unique': '该用户名已被使用',
            'required': '用户名不能为空',
            'max_length': '用户名长度不能超过100个字符'
        }
    )
    password = models.CharField(
        max_length=128, 
        verbose_name="密码",
        error_messages={
            'required': '密码不能为空',
            'max_length': '密码长度不能超过128个字符'
        }
    )
    avatar = models.ImageField(
        upload_to='avatars/', 
        null=True, 
        blank=True, 
        verbose_name="头像",
        error_messages={
            'invalid': '请上传有效的图片文件'
        }
    )
    points = models.IntegerField(
        default=0, 
        verbose_name="积分",
        error_messages={
            'invalid': '积分必须是整数'
        }
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    user_id = models.CharField(
        max_length=150, 
        unique=True, 
        verbose_name="用户ID", 
        null=True, 
        blank=True,
        error_messages={
            'unique': '用户ID已存在'
        }
    )
    last_login = models.DateTimeField(null=True, blank=True, verbose_name="最后登录时间")
    # 是否开通了联系方式
    is_contact = models.BooleanField(default=True, verbose_name="是否开通了联系方式")
    # 用户是否是管理员
    is_admin = models.BooleanField(default=False, verbose_name="是否是管理员")
    def save(self, *args, **kwargs):
        # 只在创建新用户时生成 user_id
        if not self.user_id:
            self.user_id = str(uuid.uuid4())
        # 判断密码长度
        if len(self.password) < 6:
            raise ValueError("密码长度至少为6位")
        # 检查用户名是否包含非法字符
        if not re.match(r'^[a-zA-Z0-9_\u4e00-\u9fa5]+$', self.username):
            raise ValueError("用户名只能包含字母、数字、下划线和中文")
        # 密码不能有中文或者其他违法字符，只能有@符号、数字、字母、下划线
        if not re.match(r'^[a-zA-Z0-9@_]+$', self.password):
            raise ValueError("密码只能包含字母、数字、@符号和下划线")
        super().save(*args, **kwargs)

    class Meta:
        verbose_name = "用户"
        verbose_name_plural = verbose_name
        db_table = 'users'
class Activity(models.Model):
    """活动模型"""
    STATUS_CHOICES = (
        ('draft', '未发布'),
        ('published', '已发布'),
        ('ended', '已结束'),
    )
    
    title = models.CharField(max_length=100, verbose_name="活动标题")
    description = models.TextField(verbose_name="活动描述")
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft', verbose_name="活动状态")
    cover_image = models.FileField(upload_to='activities/', null=True, blank=True, verbose_name="封面图片")
    user_id = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="创建者", to_field="user_id")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "活动"
        verbose_name_plural = verbose_name
        db_table = 'activities'

class Reward(models.Model):
    """奖励模型"""
    REWARD_TYPE_CHOICES = (
        ('physical', '实物'),
        ('points', '积分'),
        ('coupon', '优惠券'),
    )
    
    activity = models.ForeignKey(Activity, on_delete=models.CASCADE, verbose_name="所属活动")
    reward_name = models.CharField(max_length=50, verbose_name="奖励名称")
    reward_type = models.CharField(max_length=10, choices=REWARD_TYPE_CHOICES, verbose_name="奖励类型")
    quantity = models.IntegerField(verbose_name="奖励数量")
    remaining = models.IntegerField(verbose_name="剩余数量")
    image = models.FileField(upload_to='rewards/', null=True, blank=True, verbose_name="奖励图片")
    description = models.TextField(null=True, blank=True, verbose_name="奖励描述")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "奖励"
        verbose_name_plural = verbose_name
        db_table = 'rewards'

class ParticipationRecord(models.Model):
    """参与记录模型"""
    # 审核进度
    STATUS_CHOICES = (
        (1, "未审核"),
        (2, '不通过'),
        (3, '通过'),
        (4, '默认状态'),
        (5, '正在参与中')
    )
    status = models.BigIntegerField(default=4, choices=STATUS_CHOICES, verbose_name="审核进度", null=True, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="参与用户", to_field="user_id")
    activity = models.ForeignKey(Activity, on_delete=models.CASCADE, verbose_name="参与活动")
    completion_status = models.BooleanField(default=False, verbose_name="完成状态")
    completion_time = models.DateTimeField(null=True, blank=True, verbose_name="完成时间")
    reward = models.ForeignKey(Reward, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="获得奖励")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    # 完成审批或者不通过审批的留言
    remark = models.TextField(null=True, blank=True, verbose_name="留言")
    class Meta:
        verbose_name = "参与记录"
        verbose_name_plural = verbose_name
        db_table = 'participation_records'
        unique_together = ['user', 'activity']  # 确保用户不能重复参与同一活动


# 联系方式
class Contact(models.Model):
    """联系方式模型"""
    
    # 用户
    user_id = models.ForeignKey(
        User, 
        on_delete=models.CASCADE, 
        verbose_name="用户", 
        to_field="user_id",
        error_messages={'required': '用户不能为空'}
    )
    phone = models.CharField(
        max_length=11, 
        verbose_name="联系电话", 
        null=True, 
        blank=True,
        error_messages={
            'max_length': '电话号码长度不能超过11位',
            'invalid': '请输入有效的电话号码'
        }
    )
    email = models.EmailField(
        verbose_name="电子邮箱", 
        null=True, 
        blank=True,
        error_messages={
            'invalid': '请输入有效的邮箱地址'
        }
    )
    address = models.CharField(
        max_length=255, 
        verbose_name="联系地址", 
        null=True, 
        blank=True,
        error_messages={
            'max_length': '地址长度不能超过255个字符'
        }
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    
    # 社交媒体账号
    wechat = models.CharField(
        max_length=100, 
        verbose_name="微信", 
        null=True, 
        blank=True,
        error_messages={
            'max_length': '微信账号长度不能超过100个字符'
        }
    )
    weibo = models.CharField(
        max_length=100, 
        verbose_name="微博", 
        null=True, 
        blank=True,
        error_messages={
            'max_length': '微博账号长度不能超过100个字符'
        }
    )
    qq = models.CharField(
        max_length=100, 
        verbose_name="QQ", 
        null=True, 
        blank=True,
        error_messages={
            'max_length': 'QQ号长度不能超过100个字符'
        }
    )
    douyin = models.CharField(
        max_length=100, 
        verbose_name="抖音", 
        null=True, 
        blank=True,
        error_messages={
            'max_length': '抖音账号长度不能超过100个字符'
        }
    )
    kuaishou = models.CharField(
        max_length=100, 
        verbose_name="快手", 
        null=True, 
        blank=True,
        error_messages={
            'max_length': '快手账号长度不能超过100个字符'
        }
    )
    xiaohongshu = models.CharField(
        max_length=100, 
        verbose_name="小红书", 
        null=True, 
        blank=True,
        error_messages={
            'max_length': '小红书账号长度不能超过100个字符'
        }
    )
    zhihu = models.CharField(
        max_length=100, 
        verbose_name="知乎", 
        null=True, 
        blank=True,
        error_messages={
            'max_length': '知乎账号长度不能超过100个字符'
        }
    )
    other = models.CharField(
        max_length=100, 
        verbose_name="其他", 
        null=True, 
        blank=True,
        error_messages={
            'max_length': '其他账号长度不能超过100个字符'
        }
    )

    def save(self, *args, **kwargs):
        if not self.user_id.is_contact:
            raise ValueError("您必须先开通联系方式")
        super().save(*args, **kwargs)


# 系统更新
# 版本
class Version(models.Model):
    version = models.CharField(max_length=32, verbose_name='版本号', unique=True)
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    # 下载链接
    download_url = models.CharField(max_length=200, verbose_name='下载链接', validators=[check_url])

# 版本说明
class VersionDesc(models.Model):
    version = models.ForeignKey(to="Version", on_delete=models.CASCADE, verbose_name='版本号', to_field="version")
    type_choice = (
        (0, '新增'),
        (1, '优化'),
        (2, '修复'),
        (3, '删除')
    )
    type = models.IntegerField(choices=type_choice, default=0, verbose_name='类型')
    text = models.TextField(verbose_name='更新内容')




# 财务流水
class FinancialFlow(models.Model):
    """财务流水模型"""
    FLOW_TYPE_CHOICES = (
        (0, '收入'),
        (1, '支出')
    )
    flow_type = models.IntegerField(choices=FLOW_TYPE_CHOICES, verbose_name="流水类型")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    # 流水描述
    description = models.TextField(verbose_name="流水描述")
    # 流水金额
    amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="金额")
    # 操作的用户
    user_id = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="操作用户", to_field="user_id")

